package cn.virens.web.controller.open.wxmp;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;

import cn.hutool.core.util.StrUtil;
import cn.virens.Assert;
import cn.virens.common.RequestUtil;
import cn.virens.exception.APIException;
import cn.virens.web.common.BaseController;
import cn.virens.web.components.open.wxmp.WxMpServiceImpl;
import cn.virens.web.components.open.wxmp.router.WxMpRouterImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;

@Controller
@RequestMapping("open/wxmp/{appid}")
public class WxMpMessageContorller extends BaseController {
	private @Autowired WxMpServiceImpl mWxService;
	private @Autowired WxMpRouterImpl mWxRouter;

	/**
	 * 请求前置，将对应微信的appid作为当前作用域的默认配置key
	 * 
	 * @param appid 微信的appid
	 */
	@ModelAttribute
	public void init(@PathVariable("appid") String appid) {
		this.mWxService.switchoverTo(appid);
	}

	@ResponseBody
	@RequestMapping(method = RequestMethod.GET)
	public String get(HttpServletRequest request, HttpServletResponse response) {
		String signature = Assert.isEmpty(RequestUtil.getValueStr(request, "signature"), "非法请求");
		String timestamp = Assert.isEmpty(RequestUtil.getValueStr(request, "timestamp"), "非法请求");
		String echostr = Assert.isEmpty(RequestUtil.getValueStr(request, "echostr"), "非法请求");
		String nonce = Assert.isEmpty(RequestUtil.getValueStr(request, "nonce"), "非法请求");

		logger.debug("微信接口验证：" + JSON.toJSONString(request.getParameterMap()));

		if (!mWxService.checkSignature(timestamp, nonce, signature)) {
			throw new APIException("ERROR_SIGN", "非法请求");
		} else {
			return echostr;
		}
	}

	@ResponseBody
	@RequestMapping(method = RequestMethod.POST)
	public String post(@RequestBody String requestBody, HttpServletRequest request, HttpServletResponse response) {
		String msgSignature = RequestUtil.getValueStr(request, "msg_signature");
		String encryptType = RequestUtil.getValueStr(request, "encrypt_type");
		String signature = RequestUtil.getValueStr(request, "signature");
		String timestamp = RequestUtil.getValueStr(request, "timestamp");
		String nonce = RequestUtil.getValueStr(request, "nonce");

		WxMpXmlOutMessage outMessage = null;

		if (!mWxService.checkSignature(timestamp, nonce, signature)) { //
			throw new APIException("ERROR_SIGN", "非法请求，可能属于伪造的请求！");
		} else if (StrUtil.equals(encryptType, "aes")) {
			WxMpConfigStorage config = mWxService.getWxMpConfigStorage();

			// 解密微信通知的消息
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, config, timestamp, nonce, msgSignature);
			if ((outMessage = mWxRouter.route(inMessage)) != null) {
				return outMessage.toEncryptedXml(config);
			} else {
				return "";
			}
		} else {
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
			if ((outMessage = mWxRouter.route(inMessage)) != null) {
				return outMessage.toXml();
			} else {
				return "";
			}
		}
	}
}
